﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BST250301TestStand.Models.Helpers
{
    /// <summary>
    /// 一阶低通滤波器类，它支持两种使用方式：
    /// 1️⃣ 直接指定 alpha
    /// 2️⃣ 或者根据采样周期 Δt（秒）与时间常数 τ（秒）自动计算 alpha = Δt / (τ + Δt)
    /// </summary>
    internal class LowPassFilter
    {
        private double _alpha;         // 滤波系数
        private double _lastValue;     // 上次输出值
        private bool _initialized;

        /// <summary>
        /// 用直接指定的 alpha 创建滤波器 (0 < alpha ≤ 1)
        /// </summary>
        public LowPassFilter(double alpha)
        {
            SetAlpha(alpha);
        }

        /// <summary>
        /// 用时间常数 τ (RC) 与采样周期 Δt 计算 alpha
        /// </summary>
        /// <param name="tau">时间常数 τ（秒）</param>
        /// <param name="deltaT">采样周期 Δt（秒）</param>
        public LowPassFilter(double tau, double deltaT)
        {
            SetAlphaFromTimeConstant(tau, deltaT);
        }

        /// <summary>
        /// 设置滤波系数 α
        /// </summary>
        public void SetAlpha(double alpha)
        {
            if (alpha <= 0 || alpha > 1)
                throw new ArgumentOutOfRangeException(nameof(alpha), "alpha 必须在 (0, 1] 范围内");
            _alpha = alpha;
        }

        /// <summary>
        /// 根据 τ 和 Δt 计算滤波系数 α
        /// </summary>
        public void SetAlphaFromTimeConstant(double tau, double deltaT)
        {
            if (tau <= 0 || deltaT <= 0)
                throw new ArgumentOutOfRangeException("tau 和 deltaT 必须大于 0");
            _alpha = deltaT / (tau + deltaT);
        }

        /// <summary>
        /// 输入新值，返回滤波后的结果
        /// </summary>
        public double Filter(double newValue)
        {
            if (!_initialized)
            {
                _lastValue = newValue;
                _initialized = true;
                return newValue;
            }

            _lastValue = _alpha * newValue + (1 - _alpha) * _lastValue;
            return _lastValue;
        }

        /// <summary>
        /// 重置滤波器
        /// </summary>
        public void Reset(double initialValue = 0)
        {
            _lastValue = initialValue;
            _initialized = false;
        }

        /// <summary>
        /// 示例
        /// </summary>
        static void Test()
        {
            //示例 1：直接指定 α
            var filter = new LowPassFilter(alpha: 0.2);

            double[] data = { 10, 11, 15, 20, 18, 17, 19, 18, 16, 15 };

            foreach (var x in data)
            {
                double y = filter.Filter(x);
                Console.WriteLine($"{x,6:F2} -> {y,6:F2}");
            }


            //示例 2：根据 τ 和 Δt 自动计算 α
            // 假设传感器采样周期 Δt = 0.01 秒（100 Hz）
            // 时间常数 τ = 0.05 秒
            double deltaT = 0.01;
            double tau = 0.05;

            var filter2 = new LowPassFilter(tau, deltaT);

            double[] noisyData = { 10, 11, 15, 20, 18, 17, 19, 18, 16, 15 };
            foreach (var x in noisyData)
            {
                double y = filter2.Filter(x);
                Console.WriteLine($"{x,6:F2} -> {y,6:F2}");
            }

            //原始值 滤波后
            //10.00    10.00
            //11.00    10.20
            //15.00    10.96
            //20.00    12.77
            //18.00    13.82
            //17.00    14.26
            //19.00    15.01
            //18.00    15.41
            //16.00    15.33
            //15.00    15.26

            //公式说明
            //实现对应公式：
            //𝑦[𝑛]=𝛼𝑥[𝑛]+(1−𝛼)𝑦[𝑛−1]
            //y[n]=αx[n]+(1−α)y[n−1]
            //α（alpha）控制“信号变化速度”与“平滑程度”的权衡
            //α ≈ 1 → 几乎不过滤（响应快）
            //α ≈ 0.1 → 滤波强（响应慢但平滑）

        }
    }
}
